//package cn.tedu.opencv.service;
//
//import cn.tedu.common.ex.ResultCodeEnum;
//import cn.tedu.common.ex.ServiceException;
//import cn.tedu.opencv.params.RemoveParam;
//import lombok.extern.slf4j.Slf4j;
//import org.opencv.core.*;
//import org.opencv.features2d.*;
//import org.opencv.imgcodecs.Imgcodecs;
//import org.opencv.imgproc.Imgproc;
//import org.springframework.stereotype.Service;
//import org.springframework.web.multipart.MultipartFile;
//
//import java.io.*;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.nio.file.Paths;
//import java.nio.file.StandardOpenOption;
//import java.util.*;
//import java.util.stream.Collectors;
//
///**
// * 注： RATIO_THRESHOLD增大，MIN_MATCHES也需要增大 才能保持平衡
// * 注： RATIO_THRESHOLD增大，不相似的都会归为相似；MIN_MATCHES增大，相似的都会归为不相似
// * 0.6 + 200 会将某些相似图片归为不同组（应该稍减小MIN_MATCHES）
// * 0.6 + 190 可能有很不相似的图像归为一组 （稍增大MIN_MATCHES），但是有些大概相似的图像不归为一组（可能要稍增大 RATIO_THRESHOLD）
// * 0.6 + 197 刚好解决不相似的图像归为一组 的问题
// * 0.7 + 197 有明显误差
// * 0.65 + 197 误差缩小，一些相似能归为相似，但是有一部分相似还是不能归为相似
// *
// */
//
///**
// * SIFT sift = SIFT.create(1000);
// * RATIO_THRESHOLD = 0.6f
// * MIN_MATCHES = 80 宽松匹配
// * MIN_MATCHES = 150 中等匹配
// * MIN_MATCHES = 200 严格匹配
// */
//
///**
// * 不限制特征点数量
// * SIFT sift = SIFT.create();
// * RATIO_THRESHOLD = 0.6f
// * TotalMatches:1425 goodMatches:288
// *
// */
//@Service(value = "common")
//@Slf4j
//public class ImgDetectionServiceImpl implements ImgDetectionService{
//
//    private static final String FILE_SEPARATOR = File.separator;
//    private static final String OUTPUT_FOLDER = "D:" + FILE_SEPARATOR + "files" + FILE_SEPARATOR + "clearestImg2" + FILE_SEPARATOR;
//    private static final float RATIO_THRESHOLD = 0.6f;
//    private static final int MIN_MATCHES = 80;
//
//    private static final Map<Mat, String> matAndFileNameMap = new LinkedHashMap<>();
//
//    @Override
//    public List<String> detect(List<MultipartFile> files, String selectPath, double percentage) {
//        // 检查传入文件夹
//        createIfNotExist(selectPath);
//        // 初始化系统
//        initSystem();
//        // 加载图像并填充map
//        List<Mat> images = loadImages(files);
//        // 分组相似图像
//        List<List<Mat>> imageGroups = groupImagesWithSIFT(images, percentage);
//
//        // 在每个组中找到最清晰的图像
//        List<String> outputPathList = new ArrayList<>();
//        for (List<Mat> group : imageGroups) {
//            Mat clearestImage = findClearestImage(group);
//            if (clearestImage != null) {
//                String outputPath = saveImgInSelectedFolder(clearestImage, selectPath);
//                outputPathList.add(outputPath);
//            }
//        }
//        return outputPathList;
//    }
//
//    @Override
//    public List<String> group(List<MultipartFile> files, String selectPath, double percentage) {
//        createIfNotExist(selectPath);
//
//        initSystem();
//
//        // 加载图像并填充map
//        List<Mat> images = loadImages(files);
//        // 分组相似图像
//        List<List<Mat>> imageGroups = groupImagesWithSIFT(images, percentage);
//        return saveByGroup(selectPath, imageGroups);
//    }
//
////    @Override
////    public String findClearest(List<MultipartFile> files) {
////        // 解决awt报错问题
////        System.setProperty("java.awt.headless", "false");
////       // 加载动态库
////        URL url = ClassLoader.getSystemResource("lib/opencv/opencv_java3416.dll");
////        System.load(url.getPath());
////        //System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
////
////        // 加载图像并填充map
////        List<Mat> images = loadImages(files);
////        // 找到最清晰的图像
////        Mat clearestImage = findClearestImage(images);
////        return saveImgInSelectedFolder(clearestImage, OUTPUT_FOLDER);
////    }
//
//    @Override
//    public List<String> findClearestInGroups(String folderPath) {
//        initSystem();
//
//        // imread()函数读取文件绝对路径参数，参数中文件夹不能有中文，文件名不能有中文，可以允许空格，但是不允许中文和空格
//        // Mat file = imread(folderPath);
//        File folder = new File(folderPath);
//        File[] files = folder.listFiles();
//        if (files!= null) {
//            List<String> outputPathList = new ArrayList<>();
//            for (File file : files) {
//                if (file.isDirectory()) {
//                    File subfolder = new File(file.getAbsolutePath());
//                    File[] images = subfolder.listFiles();
//                    if (images!= null) {
//                        List<Mat> loadImages = new ArrayList<>();
//                        for (File image : images) {
//                            if (image.isFile()) {
//                                String inputFileName = image.getName();
//                                byte[] bytes = new byte[0];
//                                try {
//                                    bytes = Files.readAllBytes(image.toPath());
//                                } catch (IOException e) {
//                                    e.printStackTrace();
//                                }
//                                MatOfByte matOfByte = new MatOfByte(bytes);
//                                // 转化为Mat并填充matAndFileNameMap
//                                Mat mat = Imgcodecs.imdecode(matOfByte, Imgcodecs.IMREAD_COLOR);
//                                if (!mat.empty()) {
//                                    loadImages.add(mat);
//                                    matAndFileNameMap.put(mat, inputFileName);
//                                } else {
//                                    log.error("Error loading image: {}", matOfByte);
//                                }
//                            }
//                        }
//
//                        // 找到最清晰的图像
//                        Mat clearestImage = findClearestImage(loadImages);
//                        String outputPath = saveImgInSelectedFolder(clearestImage, folderPath + "\\");
//                        outputPathList.add(outputPath);
//                    }
//                }
//            }
//            return outputPathList;
//        }
//        throw new ServiceException(ResultCodeEnum.PARAMETER_ERROR, "所选文件夹为空！");
//    }
//
//    @Override
//    public String removeBlurryImages(RemoveParam removeParam) {
//
//        initSystem();
//
//        List<MultipartFile> files = removeParam.getFiles();
//        String selectPath = removeParam.getSelectPath();
//        Integer sharpnessThreshold = removeParam.getSharpnessThreshold();
//
//        createIfNotExist(selectPath);
//        try {
//            Files.createDirectories(Paths.get(selectPath + "\\达标图片"));
//            log.info("创建文件夹成功：{}", selectPath + "\\达标图片");
//            Files.createDirectories(Paths.get(selectPath + "\\不达标图片"));
//            log.info("创建文件夹成功：{}", selectPath + "\\不达标图片");
//        } catch (IOException e) {
//            throw new ServiceException(ResultCodeEnum.PARAMETER_ERROR, "创建文件夹失败！" + e.getMessage());
//        }
//        // 加载图片并计算清晰度评分
//        List<Mat> matList = loadImages(files);
//        List<Double> sharpnessScores = matList.stream().map(this::calculateSharpness).collect(Collectors.toList());
//
//        // 根据清晰度评分归类
//        for (int i = 0; i < sharpnessScores.size(); i++) {
//            Mat mat = matList.get(i);
//            log.info("阈值：{}", sharpnessScores.get(i));
//            if (sharpnessScores.get(i) >= sharpnessThreshold) {
//                saveImgInSelectedFolder(mat, selectPath + "\\达标图片\\");
//            } else {
//                saveImgInSelectedFolder(mat, selectPath + "\\不达标图片\\");
//            }
//        }
//        return "已将清晰度达标图片放入："+ selectPath + "\\达标图片\n" + "不达标图片放入：" + selectPath + "\\不达标图片";
//    }
//
//    // 解决awt报错问题以及加载opencv动态库
//    private void initSystem() {
//        // 解决awt报错问题
//        System.setProperty("java.awt.headless", "false");
//        // 加载动态库
////        URL url = ClassLoader.getSystemResource("./lib/opencv/opencv_java3416.dll");
////        System.load(url.getPath());
////        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//        InputStream inputStream = getClass().getResourceAsStream("/lib/opencv/opencv_java3416.dll");
//        log.info("读入文件流：{}", inputStream);
//        // 将 InputStream 转换为临时文件
//        File tempFile = null;
//        try {
//            tempFile = File.createTempFile("opencv_java3416", ".dll");
//            tempFile.deleteOnExit();
//
//            try (FileOutputStream out = new FileOutputStream(tempFile)) {
//                byte[] buffer = new byte[1024];
//                int bytesRead;
//                while ((bytesRead = inputStream.read(buffer)) != -1) {
//                    out.write(buffer, 0, bytesRead);
//                }
//            }
//        } catch (IOException e) {
//            log.info("异常信息:{}", e.getMessage());
//            e.printStackTrace();
//        }
//
//        // 加载临时文件
//        log.info("文件绝对路径：{}", tempFile.getAbsolutePath());
//        System.load(tempFile.getAbsolutePath());
//    }
//
//    // 判断传入文件加是否存在，不存在则创建
//    private void createIfNotExist(String selectPath) {
//        if (Files.exists(Paths.get(selectPath))) {
//            File folder = new File(selectPath);
//            if(Objects.requireNonNull(folder.listFiles()).length > 0) {
//                throw new ServiceException(ResultCodeEnum.PARAMETER_ERROR, "文件夹不为空！请选择空白文件夹");
//            }
//        } else {
//            try {
//                Files.createDirectories(Paths.get(selectPath));
//                log.info("创建文件夹成功：{}", selectPath);
//            } catch (IOException e) {
//                throw new ServiceException(ResultCodeEnum.PARAMETER_ERROR, "创建文件夹失败！");
//            }
//        }
//    }
//
//    // 在这里可以处理每个组中最清晰的图像，例如保存到文件、显示等
//    private String saveImgInSelectedFolder(Mat clearestImage, String outputFolder) {
//        // 获取输入文件的名称
//        String inputFileName = matAndFileNameMap.get(clearestImage);
//        // 获取输入文件名后缀
//        String inputFileSuffix = inputFileName.substring(inputFileName.lastIndexOf("."));
//        // 构造输出文件的路径
//        String outputPath = outputFolder + inputFileName;
//        // 编码图像为字节数组
//        MatOfByte matOfByte = new MatOfByte();
//        Imgcodecs.imencode(inputFileSuffix, clearestImage, matOfByte);
//        // 将字节数组写入文件
//        Path path = Paths.get(outputPath);
//        try {
//            Files.write(path, matOfByte.toArray(), StandardOpenOption.CREATE);
//            log.info("Clearest image saved to: {}", outputPath);
//            return outputPath;
//        } catch (IOException e) {
//            log.error("Error writing clearest image to file", e);
//        }
//        return null;
//    }
//
//    private List<String> saveByGroup(String selectPath, List<List<Mat>> imageGroups) {
//        List<String> outputPathList = new ArrayList<>();
//
//        for (int i = 0; i < imageGroups.size(); i++) {
//            String outputFolder = selectPath + "group" + (i + 1) + "\\";
//
//            try {
//                Files.createDirectories(Paths.get(outputFolder));
//            } catch (IOException e) {
//                log.error("Error creating output folder: {}", outputFolder, e);
//                continue;
//            }
//
//            for (Mat mat : imageGroups.get(i)) {
//                String outputPath = saveImgInSelectedFolder(mat, outputFolder);
//                outputPathList.add(outputPath);
//            }
//        }
//
//        return outputPathList;
//    }
//
//
//    // 处理文件上传并生成Mat对象以及文件名的Map
//    private List<Mat> loadImages(List<MultipartFile> files) {
//        List<Mat> matList = new ArrayList<>();
//        // 处理文件上传逻辑
//        if (files != null && !files.isEmpty()) {
//            for (MultipartFile file : files) {
//                String originalFilename = file.getOriginalFilename();
//                // 将 MultipartFile 转换为 OpenCV 的 Mat 对象
//                byte[] bytes;
//                try {
//                    bytes = file.getBytes();
//                } catch (IOException e) {
//                    log.error("Error reading file bytes", e);
//                    continue;
//                }
//                MatOfByte matOfByte = new MatOfByte(bytes);
//                // 转化为Mat并填充matAndFileNameMap
//                Mat image = Imgcodecs.imdecode(matOfByte, Imgcodecs.IMREAD_COLOR);
//                if (!image.empty()) {
//                    matList.add(image);
//                    matAndFileNameMap.put(image, originalFilename);
//                } else {
//                    log.error("Error loading image: {}", matOfByte);
//                }
//            }
//            log.info("Files uploaded successfully.");
//        } else {
//            log.info("No files were uploaded.");
//        }
//        return matList;
//    }
//
////    public static List<List<Mat>> groupImagesWithSIFT(List<Mat> images) {
////        List<List<Mat>> imageGroups = new ArrayList<>();
////        Set<Mat> groupedImages = new HashSet<>();
////        List<MatOfKeyPoint> keyPointsList = new ArrayList<>();
////        List<Mat> descriptorsList = new ArrayList<>();
////
////        // 使用SIFT算法提取特征
////        SIFT sift = SIFT.create();
////        for (Mat image : images) {
////            MatOfKeyPoint keyPoints = new MatOfKeyPoint();
////            Mat descriptors = new Mat();
////            sift.detectAndCompute(image, new Mat(), keyPoints, descriptors);
////
////            keyPointsList.add(keyPoints);
////            descriptorsList.add(descriptors);
////        }
////        log.info("关键点列表：" + keyPointsList);
////
////        // 进行特征匹配
////        BFMatcher matcher = BFMatcher.create();
////        for (int i = 0; i < images.size(); i++) {
////            List<Mat> group = new LinkedList<>();
////            if (!isAlreadyGrouped(groupedImages, images.get(i))) {
////                group.add(images.get(i));
////                groupedImages.add(images.get(i));
////
////                for (int j = i + 1; j < images.size(); j++) {
////                    if (!isAlreadyGrouped(groupedImages, images.get(j))) {
////                        // 使用BFMatcher进行特征匹配
////                        List<MatOfDMatch> knnMatches = new ArrayList<>();
////                        matcher.knnMatch(descriptorsList.get(i), descriptorsList.get(j), knnMatches, 2);
////
////                        // 应用比率测试
////                        List<DMatch> goodMatches = new LinkedList<>();
////                        for (MatOfDMatch matOfDMatch : knnMatches) {
////                            DMatch[] matches = matOfDMatch.toArray();
////                            if (matches[0].distance < RATIO_THRESHOLD * matches[1].distance) {
////                                goodMatches.add(matches[0]);
////                            }
////                        }
////
////                        // 如果匹配数超过阈值，将图像添加到同一组
////                        if (goodMatches.size() > MIN_MATCHES) {
////                            group.add(images.get(j));
////                            groupedImages.add(images.get(j));
////                        }
////                    }
////                }
////                // 由于groupedImages是HashSet，所以不需要手动移除
////                imageGroups.add(group);
////            }
////        }
////        return imageGroups;
////    }
//
//    private List<List<Mat>> groupImagesWithSIFT(List<Mat> images, double percentage) {
//        List<List<Mat>> imageGroups = new ArrayList<>();
//        List<MatOfKeyPoint> keyPointsList = new ArrayList<>();
//        List<Mat> descriptorsList = new ArrayList<>();
//
//        // 使用SIFT算法提取特征
//        SIFT sift = SIFT.create(5000);// 保证速度的同时，提升准确度
////        for (Mat image : images) {
////            MatOfKeyPoint keyPoints = new MatOfKeyPoint();
////            Mat descriptors = new Mat();
////            sift.detectAndCompute(image, new Mat(), keyPoints, descriptors);
////
////            keyPointsList.add(keyPoints);
////            descriptorsList.add(descriptors);
////        }
////        log.info("关键点列表：" + keyPointsList);
////
////        // 进行特征匹配
////        for (int i = 0; i < images.size(); i++) {
////            Mat imageDesc = descriptorsList.get(i);
////
////            boolean foundGroup = false;
////
////            for (List<Mat> group : imageGroups) {
////                Mat image = group.get(0);
////                int index = images.indexOf(image);
////                Mat referenceDesc = descriptorsList.get(index);
////
////                if (jjj(imageDesc, referenceDesc)) {
////                    group.add(images.get(i));
////                    foundGroup = true;
////                    break;
////                }
////            }
////
////            if (!foundGroup) {
////                List<Mat> newGroup = new LinkedList<>();
////                newGroup.add(images.get(i));
////                imageGroups.add(newGroup);
////            }
////        }
///* 可以将两个for循环合并 */
//        // 一边提取特征，一边进行匹配
//        for (int i = 0; i < images.size(); i++) {
//            Mat image = images.get(i);
//
//            MatOfKeyPoint keyPoints = new MatOfKeyPoint();
//            Mat descriptors = new Mat();
//            sift.detectAndCompute(image, new Mat(), keyPoints, descriptors);
//
//            keyPointsList.add(keyPoints);
//            descriptorsList.add(descriptors);
//
//            boolean foundGroup = false;
//
//            for (List<Mat> group : imageGroups) {
//                Mat referenceImage = group.get(0);
//                int index = images.indexOf(referenceImage);
//                Mat referenceDesc = descriptorsList.get(index);
//
//                if (isSimilar(descriptors, referenceDesc, percentage)) {
//                    group.add(image);
//                    foundGroup = true;
//                    break;
//                }
//            }
//
//            if (!foundGroup) {
//                List<Mat> newGroup = new LinkedList<>();
//                newGroup.add(image);
//                imageGroups.add(newGroup);
//            }
//        }
//
//        return imageGroups;
//    }
//
//    private boolean isSimilar(Mat descriptors1, Mat descriptors2, double percentage) {
//
//        // 进行特征匹配
//        BFMatcher matcher = BFMatcher.create();
//        // 使用BFMatcher进行特征匹配
//        List<MatOfDMatch> knnMatches = new ArrayList<>();
//        matcher.knnMatch(descriptors1, descriptors2, knnMatches, 2);
//        int totalMatchesSize = knnMatches.size();
//        log.info("TotalMatches:{}", totalMatchesSize);
//
////        if (knnMatches.size() <= 200) {
////            min_matches = 60;
////        } else if (knnMatches.size() <= 270) {
////            min_matches = 70;
////        } else if (knnMatches.size() <= 300) {
////            min_matches = 80;
////        } else if (knnMatches.size() <= 600) {
////            min_matches = 150;
////        } else if (knnMatches.size() <= 1200){
////            min_matches = 180;
////        } else if (knnMatches.size() <= 1400){
////            min_matches = 190;
////        } else if (knnMatches.size() <= 1600){
////            min_matches = 220;
////        } else if (knnMatches.size() <= 1800){
////            min_matches = 250;
////        } else if (knnMatches.size() <= 2400){
////            min_matches = 300;
////        } else {
////            min_matches = 340;
////        }
//        //min_matches = adjustMinMatches(knnMatches.size());
//        // 应用比率测试
//        List<DMatch> goodMatches = new LinkedList<>();
//        for (MatOfDMatch matOfDMatch : knnMatches) {
//            DMatch[] matches = matOfDMatch.toArray();
//            if (matches[0].distance < RATIO_THRESHOLD * matches[1].distance) {
//                goodMatches.add(matches[0]);
//            }
//        }
//        int goodMatchesSize = goodMatches.size();
//        log.info("goodMatches:{}", goodMatchesSize);
//
//        // 如果匹配数超过阈值 或 最佳匹配数超过2/3倍的总匹配数
//        // 宽松：return goodMatches.size() > 0.9 * min_matches || goodMatches.size() > 0.66 * knnMatches.size();
//        // 中等：return goodMatches.size() > 1.0 * min_matches || goodMatches.size() > 0.66 * knnMatches.size();
//        // 严格：return goodMatches.size() > 1.1 * min_matches || goodMatches.size() > 0.66 * knnMatches.size();
//        //float similarity = 0.83f;
//        //double ratio = 1.2 * similarity;
//        //return goodMatches.size() > 1.0F * min_matches || goodMatches.size() > 0.5 * knnMatches.size();
//
//        // 前面针对total小于5000的，保证good大于拟合曲线；后面针对total大于5000的，保证good大于指定数
//        if (totalMatchesSize < 5000) {
//            double ratio = percentage * 1.2;
//            return goodMatchesSize > ratio * adjustMinMatches(totalMatchesSize);
//        }else {
//            return goodMatchesSize > 350;
//        }
//    }
//
//    private int adjustMinMatches(int totalMatches) {
//        int minMatches;
//        if (totalMatches <= 200) {
//            minMatches = 60;
//        } else if (totalMatches <= 2400) {
//            minMatches = (int) (
//                    - 57.7250290718273 * Math.pow(totalMatches, 0)
//                    + 0.6585584320840243 * Math.pow(totalMatches, 1)
//                    - 7.215483822166689E-4 * Math.pow(totalMatches, 2)
//                    + 4.3686505888424346E-7 * Math.pow(totalMatches, 3)
//                    - 1.3744289750440926E-10 * Math.pow(totalMatches, 4)
//                    + 2.1036304261548967E-14 * Math.pow(totalMatches, 5)
//                    - 1.1844434932044887E-18 * Math.pow(totalMatches, 6)) + 10;
//        } else {
//            minMatches = 340;
//        }
//        return minMatches;
//    }
//
//
//
//
////    public static List<List<Mat>> groupImagesWithSIFT(List<Mat> images) {
////        List<List<Mat>> imageGroups = new ArrayList<>();
////
////        for (int i = 0; i < images.size(); i++) {
////            Mat img1 = images.get(i);
////
////            boolean foundGroup = false;
////
////            for (List<Mat> group : imageGroups) {
////                Mat referenceImage = group.get(0);
////                if (areImagesSimilar(img1, referenceImage)) {
////                    group.add(img1);
////                    foundGroup = true;
////                    break;
////                }
////            }
////
////            if (!foundGroup) {
////                List<Mat> newGroup = new LinkedList<>();
////                newGroup.add(img1);
////                imageGroups.add(newGroup);
////            }
////        }
////
////        return imageGroups;
////    }
////
////    private static boolean areImagesSimilar(Mat img1, Mat img2) {
////        MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
////        MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
////        Mat descriptors1 = new Mat();
////        Mat descriptors2 = new Mat();
////
////        ORB orb = ORB.create();
////
////        orb.detectAndCompute(img1, new Mat(), keypoints1, descriptors1);
////        orb.detectAndCompute(img2, new Mat(), keypoints2, descriptors2);
////
////        BFMatcher matcher = BFMatcher.create(BFMatcher.BRUTEFORCE_HAMMING, true);
////        List<MatOfDMatch> matches = new LinkedList<>();
////        matcher.knnMatch(descriptors1, descriptors2, matches, 1);
////
////        // Apply a ratio test to find good matches
////        float ratioThreshold = 0.6f;
////        List<DMatch> goodMatches = new LinkedList<>();
////        for (MatOfDMatch match : matches) {
////            if (match.rows() > 1) {
////                DMatch[] dm = match.toArray();
////                if (dm[0].distance < ratioThreshold * dm[1].distance) {
////                    goodMatches.add(dm[0]);
////                }
////            }
////        }
////
////        return goodMatches.size() > 10;  // Adjust this threshold based on your images
////    }
//
//    private boolean isAlreadyGrouped(Set<Mat> groupedImages, Mat image) {
//        return groupedImages.contains(image);
//    }
//
//    // 修改 findClearestImage 方法
//    private Mat findClearestImage(List<Mat> images) {
//        double maxSharpness = Double.MIN_VALUE;
//        Mat clearestImage = null;
//
//        for (Mat image : images) {
//            // 计算图像清晰度，使用前面提到的方法
//            double sharpness = calculateSharpness(image);
//
//            // 更新最清晰的图像
//            if (sharpness > maxSharpness) {
//                maxSharpness = sharpness;
//                clearestImage = image.clone(); // 克隆图像，避免修改原始图像
//                // 更新全局Map
//                String originalFilename = matAndFileNameMap.get(image);
//                matAndFileNameMap.remove(image);
//                matAndFileNameMap.put(clearestImage, originalFilename);
//            }
//        }
//
//        return clearestImage;
//    }
//
//
//    private double calculateSharpness(Mat image) {
//        Mat gray = new Mat();
//        Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY);
//
//        Mat gradientX = new Mat();
//        Mat gradientY = new Mat();
//        Imgproc.Sobel(gray, gradientX, CvType.CV_32F, 1, 0, 3, 1, 0, Core.BORDER_DEFAULT);
//        Imgproc.Sobel(gray, gradientY, CvType.CV_32F, 0, 1, 3, 1, 0, Core.BORDER_DEFAULT);
//
//        Mat magnitude = new Mat();
//        Core.magnitude(gradientX, gradientY, magnitude);
//
//        Scalar score = Core.mean(magnitude);
//
//        // 释放资源
//        gray.release();
//        gradientX.release();
//        gradientY.release();
//        magnitude.release();
//
//        return score.val[0];
//    }
//
//}
